/*
 * Copyright 2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.paboo.chart.qrcode;

import com.d_project.qrcode.ErrorCorrectLevel;
import com.d_project.qrcode.QRCode;
import org.paboo.util.LoggerFactoryUtils;
import org.paboo.util.ParameterObject;

import java.awt.image.BufferedImage;
import java.io.IOException;

/**
 * @author Leonard
 */
public class QRdUtil {

    private static LoggerFactoryUtils logger = LoggerFactoryUtils.getInstance().load(QRdUtil.class);

    public static QRCode getQRCode(QrdEntity entity) {

        QRCode qr;
        if (entity.getType() == 0) {
            qr = QRCode.getMinimumQRCode(entity.getData(), entity.getLevel());
        } else {
            qr = new QRCode();
            qr.setTypeNumber(entity.getType());
            qr.setErrorCorrectLevel(entity.getLevel());
            qr.addData(entity.getData());
            qr.make();
        }

        return qr;
    }

    public static byte[][] getQRCodeBytes(QrdEntity entity) {
        return ParameterObject.convertToZxingByteMatrix(getQRCode(entity)).getArray();
    }

    public static BufferedImage getQRCodeImage(QrdEntity entity) {
        try {
            return getQRCode(entity).createImage(entity.getSize(), entity.getMargin());
        } catch (IOException e) {
            logger.error("Create Fail!!!");
            return null;
        }
    }

    public static int parseErrorCorrectLevel(String ecl) {
        if ("L".equals(ecl) || "l".equals(ecl)) {
            return ErrorCorrectLevel.L;
        } else if ("Q".equals(ecl) || "q".equals(ecl)) {
            return ErrorCorrectLevel.Q;
        } else if ("M".equals(ecl) || "m".equals(ecl)) {
            return ErrorCorrectLevel.M;
        } else if ("H".equals(ecl) || "h".equals(ecl)) {
            return ErrorCorrectLevel.H;
        } else {
            logger.error("invalid error correct level : " + ecl);
            throw new IllegalArgumentException("invalid error correct level : " + ecl);
        }
    }

    /**
     * GIFイメージを取得する。
     *
     * @param cellSize セルのサイズ(pixel)
     * @param margin   余白(pixel)
     */
    public static GIFImage createGIFImage(QRCode qrcode, int cellSize, int margin) throws IOException {

        int imageSize = qrcode.getModuleCount() * cellSize + margin * 2;

        GIFImage image = new GIFImage(imageSize, imageSize);

        for (int y = 0; y < imageSize; y++) {

            for (int x = 0; x < imageSize; x++) {

                if (margin <= x && x < imageSize - margin
                        && margin <= y && y < imageSize - margin) {

                    int col = (x - margin) / cellSize;
                    int row = (y - margin) / cellSize;

                    if (qrcode.isDark(row, col)) {
                        image.setPixel(x, y, 0);
                    } else {
                        image.setPixel(x, y, 1);
                    }

                } else {
                    image.setPixel(x, y, 1);
                }
            }
        }

        return image;
    }

}
